package com.gitee.sergius.apitool.parser.convertor.response;

import com.gitee.sergius.apitool.constant.Constant;
import com.gitee.sergius.apitool.entity.ResponseParamEntity;
import com.gitee.sergius.apitool.annotation.ApiModel;
import com.gitee.sergius.apitool.annotation.ApiModelProperty;
import com.gitee.sergius.apitool.constant.DataType;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shawn yang
 * @version 1.0.0
 * <p><pre>用于解析{@link ApiModel}定义的封装类中{@link ApiModelProperty}标签定义的响应参数</pre>
 *
 */
public class ResponseModelToEntityConvertor {

    /**
     * 自定义封装类型转换成实体
     * @param clazz 封装类
     * @param level 该参数所处的数据层级
     */
    public static List<ResponseParamEntity> parseModelToEntity(Class clazz, int level) {
        List<ResponseParamEntity> respnseParamEntityList = new ArrayList<>();

        if(level > Constant.PARSE_DEPTH){
            return respnseParamEntityList;
        }

        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            if (!field.isAnnotationPresent(ApiModelProperty.class)) {
                continue;
            }

            ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);

            Class paramClazz = field.getType();

            String name = StringUtils.isEmpty(apiModelProperty.name())?field.getName():apiModelProperty.name();
            String desc = apiModelProperty.desc();
            boolean required = apiModelProperty.required();
            String example = apiModelProperty.example();

            if (paramClazz.isAnnotationPresent(ApiModel.class)) {
                ResponseParamEntity responseParamEntity  = new ResponseParamEntity();
                responseParamEntity.setName(name);
                responseParamEntity.setDesc(desc);
                responseParamEntity.setRequired(required);
                responseParamEntity.setExample(example);
                responseParamEntity.setType(DataType.CLASS.getName());
                responseParamEntity.setHasChild(true);
                responseParamEntity.setArray(false);
                responseParamEntity.setLevel(level);
                responseParamEntity.setChildList(parseModelToEntity(paramClazz,level + 1));

            } else {

                ResponseParamEntity responseParamEntity = ResponseNotModelToEntityConvertor.parseNotModelToEntity(field.getType(),field.getGenericType(),
                        name,desc,required,example,level);

                respnseParamEntityList.add(responseParamEntity);
            }

        }

        return respnseParamEntityList;
    }
}
